package ws.very.util.akka.mail.monitor

import scala.collection.convert.WrapAsScala
import com.typesafe.config.Config
import akka.actor.ActorRef
import akka.actor.ActorRefFactory
import akka.actor.ActorSelection
import akka.actor.ActorSelection.toScala
import akka.dispatch.Envelope
import akka.dispatch.MessageQueue

case class MonitorMsg(receiver: ActorRef, message: Any, time: Long)
case class MailBoxTakeTimeMsg(msg: Any, receiver: ActorRef, sender: ActorRef, cost: Long)
abstract trait MailboxMonitor extends MessageQueue with WrapAsScala {
  val conf: Config
  val actorFac: ActorRefFactory
  override abstract def enqueue(receiver: ActorRef, envelope: Envelope): Unit = {
    super.enqueue(receiver,
      envelope.copy(
        message = MonitorMsg(receiver, envelope.message, System.nanoTime())))
  }
  // MailBoxTakeTimeMsg(msg: Any, receiver: ActorRef, sender: ActorRef, cost: Long)
  override abstract def dequeue(): Envelope = {
    super.dequeue() match {
      case env @ Envelope(monMsg @ MonitorMsg(receiver, originMsg, enqTime), sender) =>
        logCollectAcs.foreach { _ ! MailBoxTakeTimeMsg(originMsg, receiver, sender, System.nanoTime - enqTime) }
        env.copy(message = originMsg)
      case otherEnv => otherEnv
    }
  }

  def logCollectAcs: Iterable[ActorSelection] = {
    conf.getStringList("logCollectAcs").map { actorFac.actorSelection(_) }
  }
  //  def lookUpCollectAcs(system:ActorSystem) : Iterable[ActorRef]= {
  ////    system.actorOf(Props[LogMonitor])
  //  }

}
